package com.rainbowBoot.common;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

public class BaseDao{

    // jdbc连接
    @Autowired
    private JdbcTemplate jdbc;

    /**
     * 通过传入对象执行更新
     * @param obj
     */
    public void update(Object obj) {
        // 所有方法
        Method[] methods = obj.getClass().getDeclaredMethods();
        // 表名
        String tableName;
        //sql参数
        List<Object> paramsList = new ArrayList<>();
        // 更新语句
        String sql = "update ";
        // id
        Object id = null;
        try {
            // 获取表名的方法
            Method getTableName = obj.getClass().getDeclaredMethod("getTableName");
            // 得到表名
            tableName = String.valueOf(getTableName.invoke(obj.getClass().getDeclaredConstructor().newInstance()));
            sql += tableName + "  id=id ";
            for(Method method : methods) {
                // 方法名
                String methodName = method.getName();
                if(methodName.startsWith("get") && !methodName.equals("getTableName")) {
                    // 获得属性值
                    Object value;
                    if((value = method.invoke(obj)) == null) {
                        continue;
                    } else if(methodName.equals("getId")) {
                        id = method.invoke(obj);
                    }
                    sql += "," + methodName.substring(3,methodName.length()) + "=?";
                    paramsList.add(value);
                }
            }
            paramsList.add(id);
            Object[] params = new Object[paramsList.size()];
            for(int i=0; i<paramsList.size(); i++) {
                params[i] = paramsList.get(i);
            }
            jdbc.update(sql,params);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

    }

    /**
     * 通过传入对象执行插入
     * @param obj
     */
    public void insert(Object obj) {
        // 所有方法
        Method[] methods = obj.getClass().getDeclaredMethods();
        // 表名
        String tableName;
        //sql参数
        List<Object> paramsList = new ArrayList<>();
        // 插入语句
        String sql = "INSERT INTO ";
        String frontSql = "";
        String afterSql = "";
        try {
            // 获取表名的方法
            Method getTableName = obj.getClass().getDeclaredMethod("getTableName");
            // 得到表名
            tableName = String.valueOf(getTableName.invoke(obj.getClass().getDeclaredConstructor().newInstance()));
            sql += tableName + " ( ";
            for(Method method : methods) {
                // 方法名
                String methodName = method.getName();
                if(methodName.startsWith("get") && !methodName.equals("getTableName")) {
                    // 获得属性值
                    Object value;
                    if((value = method.invoke(obj)) == null) {
                        continue;
                    }
                    frontSql += methodName.substring(3,methodName.length()) + " ,";
                    paramsList.add(value);
                }
            }
            Object[] params = new Object[paramsList.size()];
            for(int i=0; i<paramsList.size(); i++) {
                afterSql += " ?,";
                params[i] = paramsList.get(i);
            }
            sql += frontSql.substring(0,frontSql.length()-1) + " ) values (" + afterSql.substring(0,afterSql.length()-1) + " )";
            System.err.println(sql);
            jdbc.update(sql,params);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

    public List<Map<String,Object>> query(Object obj) {
        // 所有方法
        Method[] methods = obj.getClass().getDeclaredMethods();
        // 表名
        String tableName;
        // 查询sql
        String sql = "select ";
        // 查询字段sql
        String paramsSql = "";
        // 条件字段
        Map<String , Object> paramMap = new HashMap<>();
        try {
            // 获取表名的方法
            Method getTableName = obj.getClass().getDeclaredMethod("getTableName");
            // 得到表名
            tableName = String.valueOf(getTableName.invoke(obj.getClass().getDeclaredConstructor().newInstance()));
            for(Method method : methods) {
                // 方法名
                String methodName = method.getName();
                if(methodName.startsWith("get") && !methodName.equals("getTableName")) {
                    // 属性名
                    String paramName = methodName.substring(3,methodName.length());
                    // 查询所有字段
                    paramsSql += "," + paramName;
                    // 获得属性值
                    Object value;
                    if((value = method.invoke(obj)) == null) {
                        continue;
                    }
                    paramMap.put(methodName.substring(3,methodName.length()),value);
                }
            }
            paramsSql = paramsSql.substring(1,paramsSql.length());
            Object[] params = new Object[paramMap.size()];
            // 获取所有属性名
            Set mapKey = paramMap.keySet();
            sql += paramsSql + " from " + tableName + " where 1=1 and ";
            int count = 0;
            for(Object key : mapKey) {
                // 属性值
                Object objectValue = paramMap.get(key);
                sql += key.toString() + "=? and ";
                params[count] = objectValue;
                count++;
            }
            return jdbc.queryForList(sql.substring(0,sql.length()-4),params);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }
}
